/**
 * 音频编码器 FDK_AAC
 * AAC(Advanced Audio Coding):高级音频编码
 *  1.概述：
 *      出现于1997年，基于MPEG-2的音频编码技术。由Fraunhofer IIS、杜比实验室、AT&T、索尼等公司共同开发，目的
 *      取代MP3格式
 *      2000年，MPEG-4标准出现后，AAC重新集成了其特性，加入了SBR技术和PS技术，为了区别于传统的MPEG-2 AAC又称
 *      MPEG4-4 AAC
 *  2.编码规格(Profile)
 *      MPEG-2 AAC LC:低复杂度规格(Low Complexity) 注:比较简单，没有增益控制，但提高了编码效率，在中等码率的
 *          编码效率以及音质方面，都能找到平衡点
 *      MPEG-2 AAC Main:主规格
 *      MPEG-2 AAC SSR:可变采样率规格(Scaleable Sample Rate)
 *      MPEG-4 AAC LC:低复杂度规格(Low Complexity) 注:现在的手机比较常见的MP4文件中音频部分就包括了该规格
 *      MPEG-4 AAC Main:主规格 注:包含了除增益控制之外的全部功能，其音质最好
 *      MPEG-4 AAC SSR:可变采样率规格(Scaleable Sample Rate)
 *      MPEG-4 AAC LTP:长时期预测规格(Long Term Predicition)
 *      MPEG-4 AAC LD:低延迟规格(Low Delay)
 *      MPEG-4 AAC HE:高效率规格(High Efficiency) 注:这种规格适合用于低码率编码，有Nero AAC编码器支持
 *  3.封装格式
 *      1.ADIF(Audio Data Interchange Format):音频数据交换格式，该格式一般应用在将音频通过写文件方式存储在磁
 *          盘里的场景，不能进行随机访问，不允许在文件中间开始进行解码，只能拿到整个文件时才能开始进行渲染播放
 *      2.ADTS(Audio Data Transport Stream):音频数据传输流，该格式的特征是用同步字节进行将AAC音频截断，然后可
 *          以允许客户端在任何地方进行播放解码，适合网络传输场景
 *      总结来说：ADTS可以在任意帧进行解码，每一帧都有头信息，但ADIF却只有一个统一的头信息，所以必须得到所有的数据
 *          后才能解码，目前一般编码后和抽取出的基本都是ADTS格式音频流
 *      ADIF格式:这个格式比较少见，简单认识一下即可
 *          组成:adif_header + byte_alignmengt + raw_data_stream 三部分组成，其中byte_aligment用来做字节
 *              对齐，所以主要是由adif_header + raw_data_stream构成
 *              adif_sequence()
 *              {
 *                  adif_header();
 *                  byte_alignment();
 *                  raw_data_stream();
 *              }
 *              adif_header()
 *              {
 *                  adif_id;                                                    32
 *                  copyright_id_present;                                       1
 *                  if (copyright_id_present)
 *                      copyright_id;                                           72
 *                  original_copy;                                              1
 *                  home;                                                       1
 *                  bitstream_type;                                             1
 *                  bitrate;                                                    23
 *                  num_program_config_elements;                                4
 *                  if (bitstream_type == '0')
 *                      adif_buffer_fullness;                                   20
 *                  for(i = 0; i < num_program_config_elements + 1; i++) {
 *                      program_config_element();
 *                  }
 *              }
 *      ADTS格式:常用格式，必须了解
 *          组成:由若干个adts_frame组成，每个adts_frame由adts_header和raw_data_block构成
 *              adts_fixed_header(固定头信息)和adts_variable_header(可变头信息)都属于adts_header头
 *              adts_sequence()
 *              {
 *                  while(nextbits() == syncword) {
 *                      adts_frame;
 *                  }
 *              }
 *              adts_framt()
 *              {
 *                  adts_fixed_header();
 *                  adts_variable_header();
 *                  if (number_of_raw_data_blocks_in_frame == 0) {
 *                      adts_error_check();
 *                      raw_data_block();
 *                  } else {
 *                      adts_header_error_check();
 *                      for(i = 0; i <= number_of_raw_data_blocks_in_frame; i++) {
 *                          raw_data_block();
 *                          adts_raw_data_block_error_check();
 *                      }
 *                  }
 *              }
 *              adts_fixed_header()
 *              {
 *                  syncword;                                                   12
 *                  ID;                                                         1
 *                  layer;                                                      2
 *                  protection_absent;                                          1
 *                  profile_ObjectType;                                         2
 *                  sampling_frequency_index;                                   4
 *                  private_bit;                                                1
 *                  channel_configuration;                                      3
 *                  original_copy;                                              1
 *                  home;                                                       1
 *              }
 *                  字段解析：
 *                  syncword:占用12bit
 *                      所有的bit位都是1。总是0xFFF,代表一个ADTS帧的开始，作为分界符，用于同步每帧起始位置
 *                  ID:占用1bit
 *                      表示MPEG版本，0代表MPEG-4，1代表MPEG-2，一般用0
 *                  layer:占用2bit
 *                      一直是0
 *                  protenction_absent:占用1bit
 *                      0表示有CRC，整个ADST头为9字节；1表示没有CRC，整个ADTS头为7字节
 *                  profile_ObjectType:占用2bit，表示使用的AAC规格(profile)
 *                      该字段的解释取决于ID的值，如果ID=1表示MPEG-2的规格，当ID=0表示MPEG-4的规格，该字段的
 *                      值等于Audio Object Type的值减1，字段取值如下
 *                          profile_ObjectType ID=1(MPEG-2 profile) ID=0(MPEG-4 object type)
 *                          0   0b00            Main profile        AAC Main
 *                          1   0b01            Low Complexity(LC)  AAC LC
 *                          2   0b10            Scalable Sampling   AAC SSR
 *                          3   0b11            (reserved)          AAC LTP
 *                  sampling_frequency_index:占用4bit
 *                      表示采样率下标,字段取值即解释如下
 *                          sampling_frequency_index    Value
 *                          0x0                         96000
 *                          0x1                         88200
 *                          0x2                         64000
 *                          0x3                         48000
 *                          0x4                         44100
 *                          0x5                         32000
 *                          0x6                         24000
 *                          0x7                         22050
 *                          0x8                         16000
 *                          0x9                         12000
 *                          0xa                         11025
 *                          0xb                         8000
 *                          0xc                         7350
 *                          0xd                         reserved
 *                          0xe                         reserved
 *                          0xf                         escape value
 *                  private_bit:占用1bit
 *                      编码时设置0，解码时忽略
 *                  channel_configuration:占用3bit
 *                      通道配置即声道数，一般2表示立体声双声道
 *                          channel_configuration number_channel
 *                          0x0                   -
 *                          0x1                   1
 *                          0x2                   2
 *                          0x3                   3
 *                          0x4                   4
 *                          0x5                   5
 *                          0x6                   5+1
 *                          0x7                   7+1
 *                  original_copy:占用1bit
 *                      编码时设置为0，解码时忽略
 *                  home:占用1bit
 *                      编码时设置为0，解码时忽略
 *              adts_variable_header()
 *              {
 *                  copyright_identification_bit;                               1
 *                  copyright_identification_start;                             1
 *                  aac_frame_length;                                           13
 *                  adts_buffer_fullness;                                       11
 *                  number_of_raw_data_blocks_in_frame;                         2
 *              }
 *                  字段解析:
 *                      copyright_identification_bit:占用1bit
 *                          编码时设置为0，解码时忽略
 *                      copyright_identification_start:占用1bit
 *                          编码时设置为0，解码时忽略
 *                      aac_frame_length:占用13bit
 *                          当前ADTS帧的长度，包括ADTS头(固定+可变)和AAC原始流，单位byte
 *                      adts_buffer_fullness:占用11bit，0x7FF表示码率可变的码流，0x000表示固定码率的码流
 *                      number_of_raw_data_blocks_in_frame:占用2bit
 *                          该字段表示当前ADST帧中所包含的AAC帧的个数减1，为了最大的兼容性通常每个ADTS frame包
 *                          含一个AAC frame，所以该值一般为0。一个AAC原始帧包含一段时间内1024个采样及相关数据
 *               crc(16bit)
 *                  当protection_absent==0时，表示存在CRC，这里的两字节CRC，就携带了CRC信息
 *
 */

#include "FdkAACEncoder.h"

const AVCodec *FdkAACEncoder::findCodec(EncoderParam &encoderParam) {
  return avcodec_find_encoder_by_name("libfdk_aac");
}

int32_t FdkAACEncoder::initContextParam(AVCodecContext *pCodecCtx, EncoderParam &encoderParam) {
  pCodecCtx->sample_fmt = AUDIO_SAMPLE_FMT;
  pCodecCtx->frame_size = AUDIO_NB_SAMPLES;
  pCodecCtx->sample_rate = AUDIO_SAMPLE_RATE;
  pCodecCtx->bit_rate = AUDIO_BIT_RATE;
  av_channel_layout_default(&pCodecCtx->ch_layout, AUDIO_CHANNEL_NUM);
  //编码类型 低频率AAC
  pCodecCtx->profile = FF_PROFILE_AAC_LOW;

  return SUCCESS;
}

MediaType FdkAACEncoder::getMediaType() {
  return MediaType_Audio;
}

const char *FdkAACEncoder::getClassName() {
  return "FdkAACEncoder";
}

void FdkAACEncoder::toString() {
  LOG_TEST("FdkAACEncoder()")
}
